//$Id: BaseDao Dec 27, 2009 3:20:32 PM encoding UTF-8 $ QQ:199742236 $ 
package com.hd.base.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.LockMode;
import org.hibernate.type.Type;
import org.springframework.dao.DataAccessException;

/**
 * 基本Dao, 该Dao可以被任何ssh架构的应用使用
 * @author saintwe
 *
 * @version 1.0 $ Dec 27, 2009 $ 3:20:40 PM $
 *
 */
public interface BaseDao {
	
	/**
	 * 保存一个对象
	 * 
	 * @param entityName
	 * 			要保存对象的完全限定名
	 * @param entity
	 * 			 要保存的对象
	 * @throws	DataAccessException
	 */
	public void save (String entityName , Object entity) throws DataAccessException;
	
	/**
	 * 保存一个对象, 该方法与save方法的区别是: 假设Hibernate有一个saveWithGeneratorId()方法,
     * 该方法负责向数据库插入数据 在不开启事务的情况下: save方法会去调用该方法, 进行对象的保存, 然后由数据库进行回滚
     * persist()方法则不会去调用该方法
     * 
	 * @param entityName
	 * 			该对象的完整限定名
	 * @param entity
	 * 			要保存的对象
	 * @throws	DataAccessException
	 */
	public void persist (String entityName , Object entity);
	
	/**
	 * 更新一个对象
	 * 
	 * @param entityName
	 * 			该对象的完整限定名
	 * @param entity
	 * 			要保存的对象
	 * @throws	DataAccessException
	 * 			如果更新的对象为空, 则抛出异常
	 */
	public void update (String entityName , Object entity);
	
	/**
	 * 删除一个对象
	 * 
	 * @param entityName
	 * 			删除对象的完全限定名
	 * @param entity
	 * 			删除的对象
	 * @throws DataAccessException 
     * 			如果删除的对象为空, 则抛出异常
	 */
	public void delete (final String entityName ,final Object entity) throws DataAccessException;
	
	/**
     * 删除一个对象
     * @param obj
     * 		要删除的对象
     * @throws DataAccessException
     */
    public void delete(Object entity)throws DataAccessException;
	
	/**
     * 保存或者更新一个对象
     * 
     * @param entityName
     * 		要保存对象的完全限定名
     * 
     * @param entity
     * 		要保存的对象
     * @throws DataAccessException
     */
	public void saveOrUpdate(String entityName , Object entity) throws DataAccessException;
	
	/**
     * 使用Load方法加载一个对象
     * @param <T>
     * 		类型信息T
     * @param entityName
     * 		要加载对象的完全限定名
     * @param id
     * 		要加载对象的id
     * @return
     * 		T 类型的对象
     * @throws DataAccessException
     * 		如果加载对象的id不存在或者entityName为null
     */
    public <T> T load(String entityName, Serializable id) throws DataAccessException;
    
    /**
     * 从数据库中加载对象, 放入entity中, 如果缓存中存在数据, 则从缓存中获取, 否则使用GET loadType 从数据库中加载对象
     * @param entity
     * 		一个瞬时对象
     * @param id
     * 		要加载对象的id
     * @throws DataAccessException
     * 		如果对象没有找到, 或者entity为null
     */
    public void load(Object entity, Serializable id)throws DataAccessException;
    
    /**
     * 使用指定模式从数据库load对象
     * @param <T>
     * 		类型信息T
     * @param entityName
     * 		要加载对象的完全限定名或者名字
     * @param id
     * 		要加载对象的id
     * @param lockMode
     * 		Hibernate锁模式
     * @return
     * 		T 类型的对象
     * @throws DataAccessException
     */
    public <T> T load(String entityName, Serializable id, LockMode lockMode)throws DataAccessException;
	
    /**
     * 使用get方法加载对象
     * @param <T>
     * 		类型信息 T
     * @param entityName
     * 		要加载的类名
     * @param id
     * 		要加载的id
     * @return
     * 		如果未找到, 则返回null.
     * @throws DataAccessException
     */
    public <T> T get(String entityName, Serializable id) throws DataAccessException;
    
    /**
     * 使用指定模式从数据库get数据
     * @param <T>
     * 		类型信息T
     * @param entityName
     * 		要加载的类名
     * @param id	
     * 		要加载的id
     * @param lockMode
     * 		Hibernate锁模式
     * @return
     * 		如果未找到, 则返回null.
     * 
     * @throws DataAccessException
     */
    public <T> T get(String entityName, Serializable id, LockMode lockMode)throws DataAccessException;

    /**
    * 该方法从数据库中检索单个对象, 支持动态实例化结果, 可以缓存
    * @param <T>
    * @param HQL
    * @param valueMap
    * @param cacheName
    * @return
    * @throws DataAccessException
    */
   public <T> T get(String HQL, Map<String, Object> valueMap, String cacheName)throws DataAccessException;
    
   /**
    * 使用HQL从数据库查找数据, 支持分页查询
    * @param HQL
    * 		HQL语句, HQL语句需要使用命名参数的形式
    * @param valueMap
    * 		一个Map, key 为命名参数
    * @param firstResult
    * 		开始行数
    * @param maxResult
    * 		最大行数
    * @return
    * @throws DataAccessException
    */
   public <T> List<T> find(String HQL, Map<String, Object> valueMap, int firstResult, int maxResult)throws DataAccessException;
   
   /**
    * 根据条件查找对象, 并是否缓存
    * @param <T>
    * @param HQL
    * @param valueMap
    * @param cacheName
    * 		如果不指定缓存名称, 则表示不缓存
    * @return
    * @throws DataAccessException
    */
   public <T> List<T> find(String HQL, Map<String, Object> valueMap, String cacheName)throws DataAccessException;

   /**
    * 使用HQL更新或者删除数据
    * @param HQL
    * 		HQL语句
    * @param valueMap
    * 		存放值的Map
    * @return
    * 		更新或者删除后的数量
    * @throws DataAccessException
    */
   public Integer update(String HQL, Map<String, Object> valueMap)throws DataAccessException;
   
   /**
    * 使用HQL 批量更新数据
    * @param HQL
    * 		HQL
    * @param valueMap
    * 		存放值的Map
    * @return
    * @throws DataAccessException
    */
   public Integer batchUpdate(String HQL, Map<String, Object> valueMap)throws DataAccessException;
   
   /**
    * execute update, delete, batch update, batch delete by named query
    * @param namedQuery
    * @param values
    * @return
    * @throws DataAccessException
    */
   public Integer updateByNamedQuery(String namedQuery, Object ... values)throws DataAccessException;
   
   /**
    * get unique object by named query, if cacheName is not null, it will be cache data by EhCache
    * @param <T>
    * @param namedQuery
    * @param cacheName
    * @param values
    * @return
    * @throws DataAccessException
    */
   public <T> T getByNamedQuery(String namedQuery, final String cacheName, Object ... values)throws DataAccessException;
   
   /**
    * find data by named query, it will return a list if results more than zero
    * if cacheName is not null, it will be cache data,
    * if maxResult is > 0, it will be scoll result(page).
    * @param <T>
    * @param namedQuery
    * @param cacheName
    * @param beginResult
    * @param maxResult
    * @param values
    * @return
    * @throws DataAccessException
    */
   public <T> List<T> findByNamedQuery(String namedQuery, final String cacheName, int firstResult, int maxResult, Object ... values)throws DataAccessException;

	//通过sql语句查询记录条数；
	public int getListCountBySql(String sql);
	//通过sql语句查询记录；
	public List getListBySql(String sql, int currentPage, int pageNums);
	
	
	
	// ====================================================================
	/**
	 * 保存或者更新、删除
	 */
	public int saveOrUpdate( String sql ) throws Exception;
	
	/**
	 * 使用SQL语句
	 * @param sql
	 * @param beginSize
	 * @param pageSize
	 * @param valueMap
	 * @return		将结果封装至MAP, 然后返回LIST
	 */
	public List< Map< String, Object >> findListBySQLQuery( String sql, int beginSize, int pageSize, Map< String, Object  > valueMap ) throws Exception;
	
	/**
	 * 统计
	 * @param sql
	 * @param valueMap
	 * @return
	 */
	public int count( String sql, Map< String, Object > valueMap ) throws Exception;
	
	/**
	 * 查找单个数据
	 * @param sql
	 * @param valueMap
	 * @return
	 */
	public Map< String, Object > get( String sql, Map< String, Object > valueMap ) throws Exception;
	
	/**
	 * 查询单个语句,不适用参数绑定形式的
	 * @param sql
	 * @return
	 */
	public Map< String, Object > getData( String sql ) throws Exception;
	
	/**
	 * 查找全部
	 * @param sql
	 * @param valueMap
	 * @return
	 */
	public List< Map< String, Object >> findAllListBySQLQuery( String sql, Map< String, Object > valueMap ) throws Exception;
	
	public int saveAndReturnLastInsert( String sql ) throws Exception;
	
	public int batchSaveOrUpdate( List< String > sqls ) throws Exception;
	
	public List< Map< String, Object >> findListBySQLQuery( String sql, int beginSize, int pageSize, Map< String, Object> valueMap, Map< String, Type > aliasMap ) throws Exception;

	
}
